package cn.iocoder.yudao.module.system.util.a_gaojian;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;

/**
 * @author zyk
 * 图片处理工具
 */
@Slf4j
public class ImageUtils {
    public static final String IMAGE_JPG = "image/jpg";
    public static final String IMAGE_JPEG = "image/jpeg";
    public static final String IMAGE_PNG = "image/png";
    public static final String IMAGE_GIF = "image/gif";
    public static final String IMAGE_BMP = "image/bmp";
    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
            "jpg", "jpeg", "png", "gif", "bmp"
    };
    /**
     * 图片文件名最大长度
     */
    public static final int IMAGE_FILE_NAME_LENGTH_MAX = 80;
    /**
     * 图片文件大小最大限制 1MB
     */
    public static final long IMAGE_FILE_SIZE_MAX = 1 * 1024 * 1024;


    public static void main(String[] args) throws IOException {
        /*File file = new File("/ceshi/cc" + File.separator + "1b9305af1dd84a5e9a01e0e2184b586e.jpg");
        MultipartFile multipartFile = new MockMultipartFile(
                "1b9305af1dd84a5e9a01e0e2184b586e.jpg", //文件名
                "1b9305af1dd84a5e9a01e0e2184b586e.jpg", //originalName 相当于上传文件在客户机上的文件名
                MediaType.IMAGE_JPEG_VALUE, //文件类型
                new FileInputStream(file) //文件流
        );*/
        File file = new File("/ceshi/cc" + File.separator + "94725b215845bc4bcb9cb3c23385589e.mp4");
        MultipartFile multipartFile = new MockMultipartFile(
                "94725b215845bc4bcb9cb3c23385589e.mp4", //文件名
                "94725b215845bc4bcb9cb3c23385589e.mp4", //originalName 相当于上传文件在客户机上的文件名
                MediaType.IMAGE_JPEG_VALUE, //文件类型
                new FileInputStream(file) //文件流
        );
        System.out.println(upload("/ceshi", multipartFile));
    }


    /**
     * 图片上传
     *
     * @param baseDir   相对应用的基目录
     * @param imageFile 图片文件
     * @return 图片文件名称
     */
    public static String upload(String baseDir, MultipartFile imageFile) throws IOException {
        return upload(baseDir, imageFile, DEFAULT_ALLOWED_EXTENSION);
    }

    /**
     * 图片上传
     *
     * @param baseDir       相对应用的基目录
     * @param bufferedImage 图片
     * @return 图片文件名称
     */
    public static String upload(String baseDir, BufferedImage bufferedImage) throws IOException {
        String imageFileName = DateUtils.datePath() + "/" + UUID.randomUUID().toString().replaceAll("-", "") + ".jpg";
        File desc = getAbsoluteFile(baseDir, imageFileName);
        ImageIO.write(bufferedImage, "jpg", desc);
        String pathFileName = getPathFileName(imageFileName);
        return pathFileName;
    }

    /**
     * 图片上传
     *
     * @param baseDir          相对应用的基目录
     * @param imageFile        图片文件
     * @param allowedExtension 允许上传图片文件类型
     * @return 图片文件名称
     */
    public static String upload(String baseDir, MultipartFile imageFile, String[] allowedExtension) throws IOException {
        //int imageFileNameLength = imageFile.getOriginalFilename().length();
        //if (imageFileNameLength > IMAGE_FILE_NAME_LENGTH_MAX) {
        //throw new ServiceException(ApiResponseCodeEnum.FAIL, "图片文件名过长，最大长度为80字符");
        //error(200, "图片文件名过长，最大长度为80字符");
        //}

        //long size = imageFile.getSize();
        //if (IMAGE_FILE_SIZE_MAX > 0 && size > IMAGE_FILE_SIZE_MAX) {
        //  throw new ServiceException(ApiResponseCodeEnum.FAIL, "图片文件过大，最大限制为1MB");
        //error(200, "图片文件过大，最大限制为1MB");
        //}

        // 校验
        if (!assertAllowed(imageFile, allowedExtension)) {
            error(200, "图片文件格式错误，允许上传jpg,jpeg,png,gif,bmp格式");
        }

        String imageFileName = extractFilename(imageFile);

        //原本逻辑---直接上传
        //File desc = getAbsoluteFile(baseDir, imageFileName);
        //imageFile.transferTo(desc);

        //切片上传
        FileUtils.splitFile(baseDir,imageFile,imageFileName);
        String pathFileName = getPathFileName(imageFileName);

        return pathFileName;
    }

    /**
     * 校验
     *
     * @param imageFile        图片文件
     * @param allowedExtension 允许上传图片文件类型
     */
    public static Boolean assertAllowed(MultipartFile imageFile, String[] allowedExtension) {
        String extension = getExtension(imageFile);
        //  throw new ServiceException(ApiResponseCodeEnum.FAIL, "图片文件格式错误，允许上传jpg,jpeg,png,gif,bmp格式");
        return isAllowedExtension(extension, allowedExtension);
    }

    /**
     * 获取图片文件名称的后缀
     *
     * @param imageFile 图片文件
     * @return 后缀
     */
    public static String getExtension(MultipartFile imageFile) {
        String extension = FilenameUtils.getExtension(imageFile.getOriginalFilename());
        if (StringUtils.isBlank(extension)) {
            extension = getExtension(imageFile.getContentType());
        }
        return extension;
    }

    public static String getExtension(String prefix) {
        switch (prefix) {
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_PNG:
                return "png";
            case IMAGE_GIF:
                return "gif";
            case IMAGE_BMP:
                return "bmp";
            default:
                return "";
        }
    }

    /**
     * 判断MIME类型是否是允许的MIME类型
     *
     * @param extension        上传图片文件类型
     * @param allowedExtension 允许上传图片文件类型
     * @return true/false
     */
    public static boolean isAllowedExtension(String extension, String[] allowedExtension) {
        for (String str : allowedExtension) {
            if (str.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 编码文件名
     */
    public static String extractFilename(MultipartFile imageFile) {
        String extension = getExtension(imageFile);
        //String imageFileName = DateUtils.datePath() + "/" + UUID.randomUUID().toString().replaceAll("-", "") + "." + extension;
        String imageFileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + extension;
        return imageFileName;
    }

    public static File getAbsoluteFile(String uploadDir, String imageFileName) {
        File desc = new File(uploadDir + File.separator + imageFileName);
        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                desc.getParentFile().mkdirs();
            }
        }
        return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
    }

    private static String getPathFileName(String imageFileName) {
        String pathFileName = "/" + imageFileName;
        return pathFileName;
    }


    //获取文件中所有图片
    private static List<File> readFilesFromDirectory(String directoryPath) {
        File directory = new File(directoryPath);
        List<File> filesInDir = Arrays.asList(directory.listFiles());
        return filesInDir;
    }

    //查重
    public static Integer insetDuplicate(String filePath, String insetPath) throws IOException {
        File imageFile = new File(filePath);
        // 读取文件路径列表
        List<File> fileList = readFilesFromDirectory(insetPath);

        String fileMd5 = "";
        int index = 0;

        try {
            byte[] fileData = Files.readAllBytes(imageFile.toPath());
            // 计算图片的MD5值
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(fileData);
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
            }
            fileMd5 = sb.toString();
            for (File file : fileList) {
                if (!file.isDirectory() && !filePath.equals(file.getPath())) {
                    byte[] data = Files.readAllBytes(file.toPath());

                    // 计算图片的MD5值
                    digest = md.digest(data);
                    sb = new StringBuilder();
                    for (byte b : digest) {
                        sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
                    }
                    String md5Value = sb.toString();
                    // 将MD5值与文件名关联起来
                    if (fileMd5.equals(md5Value)) {
                        index++;
                    }
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return index;
    }



    public static String readImage(File input) {
        if (!input.exists()) {
            log.info("文件不存在:{}", input.getAbsolutePath());
            System.out.println("文件不存在");
        } else {
            // 检查文件权限
            log.info("文件存在:{}", input.getAbsolutePath());
            log.info("可读:{}", input.canRead());
            log.info("可写:{}", input.canWrite());
            log.info("可执行:{}", input.canExecute());
        }
        if (input == null) {
            throw new IllegalArgumentException("input == null!");
        }
        String size = "";
        try (ImageInputStream stream = ImageIO.createImageInputStream(input)) {
            BufferedImage bufferedImage = ImageIO.read(stream);
            if (bufferedImage == null) {
                log.info("图像无法读取，可能是文件损坏或格式不支持:{}", input.getAbsolutePath());
            } else {
                log.info("图像读取成功:{}", input.getAbsolutePath());
                size = bufferedImage.getWidth() + "x" + bufferedImage.getHeight();
            }
        } catch (IOException e) {
            log.error("readImage fail:" + e.getMessage());
        }
        return size;
    }

}


